package cn.golxen.blog.redis;

import cn.golxen.blog.commons.rabbitVo.*;
import cn.golxen.blog.commons.vo.GetLabelAndEssayCountVo;
import cn.golxen.blog.exception.exceptionClass.GetLabelByCategoryEmptyException;
import cn.golxen.blog.mapper.EssayLabelMapper;
import cn.golxen.blog.mapper.LabelMapper;
import cn.golxen.blog.rabbitMQ.producer.Producer;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

@Slf4j
@Component
public class LabelRedis {
    @Autowired
    @Qualifier(value = "taskExecutor")
    private ThreadPoolTaskExecutor poolTaskExecutor;
    @Autowired
    RedisTemplate<String,String> redisTemplate;
    @Autowired
    LabelMapper labelMapper;
    @Autowired
    EssayLabelMapper essayLabelMapper;
    @Autowired
    Producer producer;

//    public void deleteLabelAll(){
//        redisTemplate.delete("label_all");
//    }
//    要建队列模板，通过队列操控
//    public void deleteLabelByCategory(String category){
//        redisTemplate.delete("category:"+category+":label");
//    }

    public void deleteLabelSet(String category){
        producer.categoryProducer(new DeleteRedisLabelSetVo(category));
    }

    public void deleteEssayCountByLabel(){
        producer.categoryProducer(new DeleteRedisLabelCountVo());
    }

    public Integer getCount(){
        String countStr=redisTemplate.opsForValue().get("label_count");
        if (countStr!=null&&!countStr.isEmpty()){
            log.info("走redis");
            return Integer.valueOf(countStr);
        }else {
            log.info("走mysql");
            Integer count=labelMapper.getCount();
            poolTaskExecutor.execute(()->{
                producer.categoryProducer(new AddRedisCountByCategoryOrLabelVo(String.valueOf(count),"label"));
            });
            return count;
        }
    }


    public Set<GetLabelAndEssayCountVo> getLabelByCategory(String category){
        Set<String> setStr=redisTemplate.opsForSet().members("category:"+category+":label");

        Set<GetLabelAndEssayCountVo> setVo;
        if(setStr!=null&&!setStr.isEmpty()){
            log.info("走redis");
            setVo = new HashSet<>();
            GetLabelAndEssayCountVo vo=new GetLabelAndEssayCountVo();
            for (String voStr: setStr) {
                if (voStr.equals("此类别无标签"))
                    throw new GetLabelByCategoryEmptyException();
                vo= JSON.parseObject(voStr,GetLabelAndEssayCountVo.class);
                setVo.add(vo);
            }
        }else {
            log.info("走mysql");
            setVo = labelMapper.getLabelByCategory(category);
            log.info(setVo.toString());

            poolTaskExecutor.execute(()->{
                producer.categoryProducer(new AddRedisLabelByCategoryVo(setVo,category));
            });
            if (setVo.isEmpty())
                throw new GetLabelByCategoryEmptyException();
        }
        return setVo;
    }

    public Set<GetLabelAndEssayCountVo> getLabelAll(){
        Set<String> setStr=redisTemplate.opsForSet().members("label_all");
        Set<GetLabelAndEssayCountVo> setVo;
        if(setStr!=null&&!setStr.isEmpty()){
            log.info("走redis");
            setVo = new HashSet<>();
            GetLabelAndEssayCountVo vo=new GetLabelAndEssayCountVo();
            for (String voStr: setStr) {
                vo= JSON.parseObject(voStr,GetLabelAndEssayCountVo.class);
                setVo.add(vo);
            }
        }else {
            log.info("走mysql");
            setVo=labelMapper.getLabelAll();
            poolTaskExecutor.execute(()->{
                producer.categoryProducer(new AddRedisLabelAllVo(setVo));
            });
        }
        return setVo;
    }

    public String getEssayCountByLabel(String label){
        String count=redisTemplate.opsForValue().get("label:"+label+":count_essay");
        if (count!=null){
            log.info("走redis");
            return count;
        }else {
            log.info("走mysql");
            count= String.valueOf(essayLabelMapper.getCountByLabel(label));
            String finalCount = count;
            poolTaskExecutor.execute(()->{
                producer.categoryProducer(new AddRedisCountOfLabelVo(finalCount,label));
            });
            return count;
        }
    }
}
